/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pe.edu.upc.dew.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import pe.edu.upc.dew.model.Cliente;
import pe.edu.upc.dew.model.Dia;
import pe.edu.upc.dew.model.Hora;
import pe.edu.upc.dew.model.Horario;
import pe.edu.upc.dew.model.Local;
import pe.edu.upc.dew.model.Paquete;
import pe.edu.upc.dew.model.Servicio;
import pe.edu.upc.dew.model.Venta;
import pe.edu.upc.dew.service.UtilService;
import pe.edu.upc.dew.service.UtilServiceImpl;
import pe.edu.upc.dew.service.VentaService;
import pe.edu.upc.dew.util.ConstantesGimnasio;
import pe.edu.upc.dew.util.Util;

/**
 *
 * @author Pedro
 */
public class VentasServlet extends HttpServlet {

    private VentaService ventaService;
    private UtilService utilService;


    @Override
    public void init(ServletConfig config) throws ServletException {
        ApplicationContext context = 
            WebApplicationContextUtils.getWebApplicationContext(
                config.getServletContext());
        this.ventaService = context.getBean("ventaService", VentaService.class);
        this.utilService = context.getBean("utilService", UtilService.class);

    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        doPost(request, response);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        try{
            String accion = request.getParameter("accion");
            if(ConstantesGimnasio.ACCION_ACTUALIZAR.equals(accion)){
                //Se asigna la lista de Servicios
                String codLocalSelected = request.getParameter("cboLocales");
                List<Servicio> servicios = obtenerServiciosPorLocal(request,codLocalSelected);
                request.getSession(false).setAttribute(ConstantesGimnasio.LISTA_SERVICIOS_SESSION, servicios);
                request.setAttribute(ConstantesGimnasio.LOCAL_REQUEST, codLocalSelected);

                //Se obtiene la venta de la interface de usuario
                Venta venta = obtenerVentaDePantalla(request);
                request.getSession(false).setAttribute(ConstantesGimnasio.LISTA_SERVICIOS_SELEC_SESSION, venta.getLocal().getServicio());

                //Se actualiza el Horario
                List<Dia> horario = obtenerHorarioVenta(request);
                request.getSession(false).setAttribute(ConstantesGimnasio.LISTA_HORARIO_SESSION, horario);

                //Se calcula el total de la venta
                Double total = 0.0;
                if(venta.getLocal().getServicio() != null && venta.getPaquete() != null){
                    for (Iterator it = venta.getLocal().getServicio().iterator(); it.hasNext();) {
                        Servicio servicio = (Servicio)it.next();
                        total += (servicio.getCosto()*venta.getPaquete().getMeses());
                    }
                }
                if(venta.getPaquete() != null){
                    total += venta.getPaquete().getCosto();
                }
                venta.setTotalCosto(total);
                request.getSession(false).setAttribute(ConstantesGimnasio.VENTA_SESSION, venta);

            }else if(ConstantesGimnasio.ACCION_REGISTRAR.equals(accion)){
                //Se obtiene la venta de la interface de usuario
                Venta venta = obtenerVentaDePantalla(request);

                //Se envia a registrar
                Calendar cal = Calendar.getInstance();
                cal.add(Calendar.MONTH,venta.getPaquete().getMeses());
                venta.setFinContrato(cal.getTime());
                request.getSession(false).setAttribute(ConstantesGimnasio.VENTA_SESSION, venta);

                //para obtener el numero maximo de matriculados
                 int count = 0;

                 //crear atributo cantidad de matriculados. en el count ++ ir aumentando la cantidad de matriculados para cada
                 //servicio matriculado a servSelect,luego en la lista serviciosSelected preguntar la cantidad de msatriculados vs cantidadmaxima
                 //si se pasa botar el mensaje, llamar a setear mensaje el nombre del servicio
                List<Venta> ventas;
                if(request.getSession(false).getAttribute(ConstantesGimnasio.LISTA_VENTAS_SESSION)!= null){
                     ventas = (List<Venta>)request.getSession(false).getAttribute(ConstantesGimnasio.LISTA_VENTAS_SESSION);
                     List<Servicio> serviciosSelected = (List<Servicio>)request.getSession(false).getAttribute(ConstantesGimnasio.LISTA_SERVICIOS_SELEC_SESSION);

                     for (Iterator<Venta> it = ventas.iterator(); it.hasNext();) {
                        Venta venta1 = it.next();
                        for (Iterator<Servicio> it1 = venta1.getLocal().getServicio().iterator(); it1.hasNext();) {
                            Servicio servicio = it1.next();
                            for (Iterator<Servicio> it2 = serviciosSelected.iterator(); it2.hasNext();) {
                                Servicio servSelect = it2.next();
                                 if(servicio.getCodigo()== servSelect.getCodigo()){
                                    count += servSelect.getCantidadMatriculados();
                                   servSelect.setCantidadMatriculados(count + 1);
                                 }
                            }
                        }
                    }

                    for (Iterator<Servicio> it2 = serviciosSelected.iterator(); it2.hasNext();) {
                         Servicio servSelect = it2.next();
                         if(servSelect.getCantidadMatriculados() > servSelect.getLimiteMatriculados()){
                             mostrarMensaje(ConstantesGimnasio.MENSAJE_ERROR_LIMITE_MATRICULADOS,request,servSelect.getDescripcion());
                             request.getRequestDispatcher("Vendedor/registroVentas.jsp").forward(request, response);
                             return;
                         }
                    }
                }else{
                    ventas = new ArrayList<Venta>();
                }

                ventas.add(venta);
                request.getSession(false).setAttribute(ConstantesGimnasio.LISTA_VENTAS_SESSION, ventas);

                boolean resp = ventaService.registrarVenta(venta);

                if(resp){
                    mostrarMensaje(ConstantesGimnasio.MENSAJE_REGISTRO_EXITOSO,request, " ");
                    request.getSession(false).removeAttribute(ConstantesGimnasio.VENTA_SESSION);
                    request.getSession(false).setAttribute(ConstantesGimnasio.VENTA_RESUMEN_SESSION, venta);
                    request.setAttribute(ConstantesGimnasio.REGISTRO_EXITOSO, 1);
                }else{
                    mostrarMensaje(ConstantesGimnasio.MENSAJE_REGISTRO_ERROR,request, " ");
                }
                
            }else if(ConstantesGimnasio.ACCION_VERIFICAR_CLIENTE.equals(accion)){
                Venta venta = obtenerVentaDePantalla(request);
                venta.getCliente().setCodigo(1);
                venta.getCliente().setNombre("Juan Perez");
                request.getSession(false).setAttribute(ConstantesGimnasio.VENTA_SESSION, venta);
            }
        }catch(NumberFormatException nfex){
            mostrarMensaje(ConstantesGimnasio.MENSAJE_ERROR_DATOS_OBLIGATORIOS,request, " ");
        }
        request.getRequestDispatcher("Vendedor/registroVentas.jsp").forward(request, response);
    }

    private Venta obtenerVentaDePantalla(HttpServletRequest request){

        Venta venta = (Venta)request.getSession(false).getAttribute(ConstantesGimnasio.VENTA_SESSION);

        if(venta == null){
            venta = new Venta();
        }
        venta.setCodigo(1);
        venta.setTotalCosto(Util.getDatoDoublePantalla("txtCostoTotal",request));

        if(venta.getCliente() == null){
            venta.setCliente(new Cliente());
        }
        venta.getCliente().setDni(Util.getDatoStringPantalla("txtDNI",request));
        venta.getCliente().setNombre(Util.getDatoStringPantalla("txtNombre",request));

        Paquete paquete = Util.obtenerPaquetePantalla("cboPaquetes",ConstantesGimnasio.LISTA_PAQUETES_CONTEXTO,request);

        venta.setPaquete(paquete);

        Local local = new  Local();
        local.setCodigo(Util.getDatoDoublePantalla("cboLocales", request).intValue());
        local.setServicio(Util.obtenerOpcionesMultiplesPantalla("cboServicio",ConstantesGimnasio.LISTA_SERVICIOS_SESSION,request));

        //Se obtienen los servicios seleccionados
        venta.setLocal(local);
        return venta;
    }

    private void mostrarMensaje(String mensaje,HttpServletRequest req, String newMensaje) {
        req.setAttribute(ConstantesGimnasio.MENSAJE_REQUEST,mensaje);
        req.setAttribute(ConstantesGimnasio.MENSAJE_REQUEST_ADICIONAL_0,newMensaje);
    }

    private List<Servicio> obtenerServiciosPorLocal(HttpServletRequest request, String codLocalSelected) {
        List<Local> locales = (List<Local>)request.getSession(false).getServletContext().getAttribute(ConstantesGimnasio.LISTA_LOCALES_CONTEXTO);
        List<Servicio> serviciosList = new ArrayList<Servicio>();
        Integer codLoc = Integer.parseInt(codLocalSelected);
        for (Iterator<Local> it = locales.iterator(); it.hasNext();) {
            Local local = it.next();
            if(codLoc.equals(local.getCodigo()) && local.getServicio() != null ){
                return local.getServicio();
            }
        }
        /*if(servicios != null){
            for (int i = 0; i < servicios.length; i++) {
                servicio = (Servicio)servicios[i];
                serviciosList.add(servicio);
            }
        }*/
        return serviciosList;
    }

    private List<Dia> obtenerHorarioVenta(HttpServletRequest request){
        List<Servicio> servList = (List<Servicio>) request.getSession(false).getAttribute("LISTA_SERVICIOS_SELEC_SESSION");
        List<Dia> horarioDIAS = utilService.diasSemana();
        
        //dentro del if debo decir: para este dia para esta hora hay
        //un servicio, y ese servicio lo inserto al horario resultante
        //Se agregan los servicios al calendario de horas y dias.
        for (Iterator<Dia> it = horarioDIAS.iterator(); it.hasNext();) {
            Dia diaSemana = it.next();
            for (Iterator<Hora> it1 = diaSemana.getHora().iterator(); it1.hasNext();) {
                Hora hora = it1.next();
                for (Iterator<Servicio> it2 = servList.iterator(); it2.hasNext();) {
                    Servicio servicio = it2.next();
                    for (Iterator<Horario> it3 = servicio.getHorario().iterator(); it3.hasNext();) {
                        Horario horarioServicio = it3.next();
                        if(diaSemana.getNombre().equals(horarioServicio.getDia())
                                && hora.getCodigo() >= Util.convertirStringHoraAEntero(servicio.getHoraInicio())
                                && hora.getCodigo() <= Util.convertirStringHoraAEntero(servicio.getHoraFin())){
                            if(hora.getServicio() == null ){
                                hora.setServicio(new ArrayList<Servicio>());
                            }else{
                                //Se identifican los cruces de horario.
                                hora.setIndCruce(1);
                            }
                            hora.getServicio().add(servicio);
                            break;
                        }
                    }
                }
            }    
        }
        
        return horarioDIAS;
    }
    public void ventaService(VentaService ventaService){
        this.ventaService = ventaService;
    }

    public void setUtilService(UtilService utilService) {
        this.utilService = utilService;
    }
}